package tat.domain.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Observable;

import tat.domain.AllDomainModelRelations;
import tat.domain.DomainModelRelation;
import tat.domain.TatClass;
import tat.domain.UseCaseRelation;

public class AllDomainModelRelationsImpl implements AllDomainModelRelations {

	private Map<String, DomainModelRelation> map = new HashMap<String, DomainModelRelation>();
	private Map<DomainModelRelation, String> inverseMap = new HashMap<DomainModelRelation, String>();
	
    @Override
    public void add(final DomainModelRelation relation) {
    	map.put(relation.name(), relation);
    	inverseMap.put(relation, relation.name());
        relation.addObserver(this);
    }

    @Override
    public DomainModelRelation find(final String relationName) {
        return map.get(relationName);
    }

    @Override
    public void remove(final DomainModelRelation relation) {
        map.remove(relation.name());
        inverseMap.remove(relation);
        relation.deleteObserver(this);
    }

	@Override
	public String domainModelRelationsAsText() {
		String text = "";
		Iterator<DomainModelRelation> relations = map.values().iterator();
		while(relations.hasNext()){
			text = text + relations.next().toString();
		}
		return text;
	}
	
	@Override
	public String domainModelRelationsAsXML() {
		String text = "";
		Iterator<DomainModelRelation> relations = map.values().iterator();
		while(relations.hasNext()){
			text = text + relations.next().toXML();
		}
		return text;
	}

	@Override
	public DomainModelRelation[] conferDomainModelRealtions() {
		return map.values().toArray( new DomainModelRelation[map.size()] );
	}
	
	public boolean containsDerivedRelations(final TatClass tatClass) {
        Collection<DomainModelRelation> relations = map.values();
        boolean contains = false;
        for(DomainModelRelation relation : relations){
        	if( relation.origin().tatClass().equals(tatClass)){
        		contains = true;
        	}
        	if( relation.destination().tatClass().equals(tatClass)){
        		contains = true;
        	}
        }
        return contains;
    }
	
	public DomainModelRelation[] identifyDerivedRelations(final TatClass tatClass){
		List<DomainModelRelation> identifiedrelations = new ArrayList<DomainModelRelation>();
		 Collection<DomainModelRelation> relations = map.values();
		for(DomainModelRelation relation : relations){
        	if( relation.origin().tatClass().equals(tatClass)){
        		identifiedrelations.add(relation);
        	}
        	else if( relation.destination().tatClass().equals(tatClass)){
        		identifiedrelations.add(relation);
        	}
        }
		return identifiedrelations.toArray(new DomainModelRelation[identifiedrelations.size()]);
	}

	@Override
	public void update(Observable o, Object arg) {
		DomainModelRelation modifiedRelation = (DomainModelRelation) o;		
		String oldName = inverseMap.get(modifiedRelation);
		map.remove(oldName);
		map.put(modifiedRelation.name(), modifiedRelation);
		inverseMap.remove(modifiedRelation);
		inverseMap.put(modifiedRelation, modifiedRelation.name());		
	}
	

}
